﻿using System;
using System.Data;
using System.Data.Common;

namespace Sofire.Data
{
    public partial class QueryEngineBase
    {
        internal DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(DbConnection connection, DbTransaction transaction, ExecuteCommand command, bool autoClosed)
            where TDataSet : DataSet, new()
        {
            TDataSet value = new TDataSet();
            Exception exception = null;
            DbCommand dbCommand = this.CreateCommand(connection, command);
            DbDataAdapter dataAdpater = this.CreateDataAdapter(dbCommand);

            if(transaction != null) dbCommand.Transaction = transaction;

            command.Aborted = false;
            var userToken = this.OnExecuting(ExecuteType.DataSet, command);

            try
            {
                if(connection.State == ConnectionState.Closed) connection.Open();
                dataAdpater.Fill(value, command.TableName);
            }
            catch(Exception ex)
            {
                if(command.Aborted)
                {
                    exception = ExecuteAbortException.Instance;
                }
                else
                {
                    exception = ex;
                }
            }
            finally
            {
                if(autoClosed) connection.TryClose();
            }
            DataSetResult<TDataSet> result = new DataSetResult<TDataSet>();

            result.Initialization(this, dbCommand, value, exception);

            this.OnExecuted(ExecuteType.DataSet, result, command, userToken);
            return result;
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="command">执行查询的命令。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(ExecuteCommand command)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(this.CreateConnection(), null, command, true);
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">匹配 Name/Value 的参数集合或 数组。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, params object[] parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, ExecuteParameterCollection parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, params ExecuteParameter[] parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="anonymousInsatnce">匿名类型的实例。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, object anonymousInsatnce)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, new ExecuteParameterCollection(anonymousInsatnce)));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="command">执行查询的命令。</param>
        public DataSetResult ExecuteDataSet(ExecuteCommand command)
        {
            return new DataSetResult(this.ExecuteDataSet<DataSet>(command));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        public DataSetResult ExecuteDataSet(string commandText)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult ExecuteDataSet(string commandText, ExecuteParameterCollection parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">匹配 Name/Value 的参数集合或 数组。</param>
        public DataSetResult ExecuteDataSet(string commandText, params object[] parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult ExecuteDataSet(string commandText, params ExecuteParameter[] parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="objectInstance">任意类型的实例。</param>
        public DataSetResult ExecuteDataSet(string commandText, object objectInstance)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, new ExecuteParameterCollection(objectInstance)));
        }

    }

    public partial class QueryContext
    {
        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="command">执行查询的命令。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(ExecuteCommand command)
            where TDataSet : DataSet, new()
        {
            return this.Engine.ExecuteDataSet<TDataSet>(this.Connection, this.Transaction, command, false);
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">匹配 Name/Value 的参数集合或 数组。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, params object[] parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, ExecuteParameterCollection parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, params ExecuteParameter[] parameters)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <typeparam name="TDataSet">数据集的类型。</typeparam>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="anonymousInsatnce">匿名类型的实例。</param>
        public DataSetResult<TDataSet> ExecuteDataSet<TDataSet>(string commandText, object anonymousInsatnce)
            where TDataSet : DataSet, new()
        {
            return this.ExecuteDataSet<TDataSet>(new ExecuteCommand(commandText, new ExecuteParameterCollection(anonymousInsatnce)));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="command">执行查询的命令。</param>
        public DataSetResult ExecuteDataSet(ExecuteCommand command)
        {
            return new DataSetResult(this.ExecuteDataSet<DataSet>(command));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        public DataSetResult ExecuteDataSet(string commandText)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult ExecuteDataSet(string commandText, ExecuteParameterCollection parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">匹配 Name/Value 的参数集合或 数组。</param>
        public DataSetResult ExecuteDataSet(string commandText, params object[] parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="parameters">参数集合。</param>
        public DataSetResult ExecuteDataSet(string commandText, params ExecuteParameter[] parameters)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, parameters));
        }

        /// <summary>
        /// 执行查询，并返回一个数据集。
        /// </summary>
        /// <param name="commandText">Transact-SQL 语句。第一个字符为“>”时，表示一个存储过程。</param>
        /// <param name="objectInstance">任意类型的实例。</param>
        public DataSetResult ExecuteDataSet(string commandText, object objectInstance)
        {
            return this.ExecuteDataSet(new ExecuteCommand(commandText, new ExecuteParameterCollection(objectInstance)));
        }
    }
}